package com.pactera.madp.cp.service.impl;

import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pactera.madp.admin.api.dto.UserInfo;
import com.pactera.madp.admin.api.feign.RemoteUserService;
import com.pactera.madp.common.core.constant.SecurityConstants;
import com.pactera.madp.common.core.exception.CheckedException;
import com.pactera.madp.common.core.util.R;
import com.pactera.madp.common.data.tenant.TenantContextHolder;
import com.pactera.madp.common.security.service.MadpUser;
import com.pactera.madp.common.security.util.SecurityUtils;
import com.pactera.madp.cp.api.dto.corp.CorpDto;
import com.pactera.madp.cp.api.entity.*;
import com.pactera.madp.cp.api.entity.wm.WorkMsgConfigEntity;
import com.pactera.madp.cp.api.vo.corp.CorpPageItemVO;
import com.pactera.madp.cp.api.page.SubPage;
import com.pactera.madp.cp.common.util.DateUtils;
import com.pactera.madp.cp.config.ConstantConfig;
import com.pactera.madp.cp.job.sync.WorkEmpServiceSyncLogic;
import com.pactera.madp.cp.mapper.corp.CorpMapper;
import com.pactera.madp.cp.service.*;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.security.MessageDigest;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @description:
 * @author: Huayu
 * @time: 2020/11/23 20:19
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class CorpServiceImpl extends ServiceImpl<CorpMapper, CorpEntity> implements ICorpService {

    @Autowired
    private IWorkMsgConfigService msgConfigService;
    @Autowired
    private IWorkEmployeeService employeeServiceImpl;
    @Autowired
    private ITenantService tenantServiceImpl;
    @Autowired
    private WorkEmpServiceSyncLogic workEmpServiceSyncLogic;
    @Autowired
    private RemoteUserService remoteUserService;
    @Autowired
    private IWorkAgentService workAgentService;
    @Value("${wx.sendMsg.appName}")
    private String wxSendMsgAppName;

    @Override
    public CorpEntity getCorpInfoById(Integer corpId) {
        return this.getById(corpId);
    }

    @Override
    public CorpEntity getCorpByWxCorpId(String wxCorpId) {
        if(StrUtil.isEmpty(wxCorpId)) {
            return null;
        }
        CorpEntity corpEntity = this.getOne(Wrappers.<CorpEntity>lambdaQuery()
                .eq(CorpEntity::getWxCorpId,wxCorpId),false);

        return corpEntity;
    }

    @Override
    public List<CorpEntity> getCorpListById(Integer userId) {
        List<WorkEmployeeEntity> workEmployeeList = employeeServiceImpl.getWorkEmployeeByLogUserId(userId);
        LinkedList<CorpEntity> corpList = new LinkedList<>();
        for(WorkEmployeeEntity workEmployeeEntity : workEmployeeList){
            CorpEntity corpEntity = this.getCorpInfoById(workEmployeeEntity.getCorpId());
            if(corpEntity != null){
                if(corpEntity.getDefaultEnable()){
                    //设置默认企业为列表第一个
                    corpList.addFirst(corpEntity);
                }else{
                    corpList.add(corpEntity);
                }
            }
        }
        return corpList;
    }

    @Override
    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    public R createCorp(CorpDto corpDto) {
        //去重处理
        int count = this.count(Wrappers.<CorpEntity>lambdaQuery()
                .eq(CorpEntity::getWxCorpId,corpDto.getWxCorpId())
                .eq(CorpEntity::getTenantId, TenantContextHolder.getTenantId()));
        if (count > 0) {
            return R.failed("企业已存在,不能重复添加");
        }

        //事件回调地址
        String callBackUrl = ConstantConfig.getApiUrl() + "/cp/wework" + File.separator + "callback";

        String token = "" + System.currentTimeMillis() + new Random().nextInt(999999999);
        MessageDigest md = MessageDigest.getInstance("md5");
        byte[] tokenMd5Byte = md.digest(token.getBytes());
        token = HexUtil.encodeHexStr(tokenMd5Byte);

        String byteStr = org.apache.commons.codec.binary.Base64.encodeBase64String(UUID.randomUUID().toString().replaceAll("-", "").getBytes());
        String encodingAesKey = byteStr.replace("=", "");
        CorpEntity corpEntity = new CorpEntity();
        BeanUtils.copyProperties(corpDto, corpEntity);
        corpEntity.setToken(token);
        corpEntity.setCreateTime(LocalDateTime.now());
        corpEntity.setEncodingAesKey(encodingAesKey);
        corpEntity.setEventCallback(callBackUrl);

        count = this.count(Wrappers.lambdaQuery());
        if (count > 0) {
            return R.failed("创建企业失败，只允许创建一个企业");
        }
        corpEntity.setDefaultEnable(true);
        //企业授信
        boolean flag = this.save(corpEntity);
        if(!flag) {
            return R.failed("创建企业失败");
        }
        //获取企业id
        Integer corpId = corpEntity.getCorpId();

        corpEntity.setEventCallback(callBackUrl + "?cid=" + corpId);
        this.updateCorpByCorpId(corpEntity);

        //会话存档-配置
        WorkMsgConfigEntity workMsgConfigEntity = new WorkMsgConfigEntity();
        workMsgConfigEntity.setCorpId(corpId);
        workMsgConfigEntity.setChatApplyStatus(1);
        workMsgConfigEntity.setWhiteServerIps(JSONUtil.toJsonStr(new ArrayList<String>()));
        workMsgConfigEntity.setCreateTime(LocalDateTime.now());
        msgConfigService.createWorkMessageConfig(workMsgConfigEntity);
        log.info("创建企业成功>>>>>>>>>corpId" + corpId);

        //同步企业通讯录信息
        //workEmpServiceSyncLogic.onSyncWxEmp(corpId);
        //同步企业通讯录信息到madp系统
        //workEmpServiceSyncLogic.onSyncSysUser(corpId);
        return R.ok();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateCorpByCorpId(CorpEntity corpEntity) {
        return this.updateById(corpEntity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R bindCorp() {
        //获取登录用户信息
        MadpUser madpUser = SecurityUtils.getUser();
        //查询当前登录用户手机
        R<UserInfo> result = remoteUserService.info(madpUser.getUsername(), SecurityConstants.FROM_IN);
        String mobile = result.getData().getSysUser().getPhone();

        //绑定用户和企业信息
        WorkEmployeeEntity entity = new WorkEmployeeEntity();
        entity.setLogUserId(madpUser.getId());
        boolean flag = employeeServiceImpl.update(entity, Wrappers.<WorkEmployeeEntity>lambdaQuery().eq(WorkEmployeeEntity::getMobile,mobile));
        if(!flag){
            log.error("用户"+ madpUser.getId() + "关联企业信息失败");
            return R.ok();
        }

        //企业id列表
        List<Integer> corpIds = new ArrayList<>();
        List<WorkEmployeeEntity> entityList= employeeServiceImpl.getWorkEmployeesByMobile(mobile,"*");
        if(!entityList.isEmpty()){
            for (WorkEmployeeEntity emp : entityList){
                if(emp.getStatus() == 1){
                    AccountService.updateCorpIdAndEmployeeId(emp.getLogUserId(), emp.getCorpId(), emp.getId());
                    AccountService.setCorpAccessToken(emp.getLogUserId(), emp.getCorpId(), emp.getId());
                    corpIds.add(emp.getCorpId());
                }else {
                    log.error("用户"+ madpUser.getId() + "关联企业"+ emp.getCorpId() +"失败:status==" + emp.getStatus());
                }
            }
        }
        //返回企业列表
        List corps = this.getCorpListById(madpUser.getId())
                .stream()
                .map(corp -> {
                    Map corpInfo = new HashMap();
                    corpInfo.put("corpId",corp.getCorpId());
                    corpInfo.put("corpName",corp.getCorpName());
                    return corpInfo;
                }).collect(Collectors.toList());
        Map resp = new HashMap();
        resp.put("corps",corps);
        return R.ok(resp);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R defaultCorp(Integer corpId) {
        List<CorpEntity> updateList = new ArrayList<>();
        //查询原默认企业并设置为非默认企业
        List<CorpEntity> corpList = this.list(Wrappers.<CorpEntity>lambdaQuery()
                .eq(CorpEntity::getDefaultEnable,Boolean.TRUE));
        for(CorpEntity corpEntity : corpList) {
            corpEntity.setDefaultEnable(Boolean.FALSE);
            updateList.add(corpEntity);
        }

        //设置新默认企业
        CorpEntity entity = new CorpEntity();
        entity.setCorpId(corpId);
        entity.setDefaultEnable(Boolean.TRUE);
        updateList.add(entity);
        //更新
        boolean flag = this.updateBatchById(updateList);

        return flag ? R.ok() : R.failed();
    }

    @Override
    public List<CorpEntity> getCorpIds(String clStr){
        QueryWrapper<CorpEntity> QueryWrapper = new QueryWrapper<>();
        QueryWrapper.select(clStr+ " as corpId");
        List<CorpEntity> corpList = this.list(QueryWrapper);
        return corpList;
    }

    @Override
    public R getCorpPageList(Page page) {
        this.page(page);
        List<CorpEntity> corpEntityList = page.getRecords();
        List<CorpPageItemVO> voList = new ArrayList<>();
        for (CorpEntity corpEntity : corpEntityList) {
            WorkMsgConfigEntity workMsgConfigEntity = msgConfigService.getByCorpId(corpEntity.getCorpId());
            CorpPageItemVO vo = new CorpPageItemVO();
            vo.setCorpId(corpEntity.getCorpId());
            vo.setCorpName(corpEntity.getCorpName());
            vo.setWxCorpId(corpEntity.getWxCorpId());
            vo.setCreateTime(DateUtils.asString(corpEntity.getCreateTime()));
            vo.setDefaultEnable(corpEntity.getDefaultEnable());
            if(workMsgConfigEntity != null){
                vo.setChatApplyStatus(workMsgConfigEntity.getChatApplyStatus());
                vo.setChatStatus(workMsgConfigEntity.getChatStatus());
                vo.setMessageCreateTime(DateUtils.asString(workMsgConfigEntity.getCreateTime()));
            }
            voList.add(vo);
        }

        SubPage subPage = new SubPage();
        subPage.setRecords(voList);
        subPage.setCurrent(page.getCurrent());
        subPage.setSize(page.getSize());
        subPage.setTotal(page.getTotal());
        return R.ok(subPage);
    }

    @Override
    public List<CorpEntity> getCorps(String id) {
        QueryWrapper<CorpEntity> corpEntityQueryWrapper = new QueryWrapper<>();
        List<CorpEntity> corpList = this.baseMapper.selectList(corpEntityQueryWrapper);
        return corpList;
    }

    @Override
    public Integer getWxSendMsgAgentIdByWxCorpId(String wxCorpId) {
        CorpEntity corpEntity = this.getOne(new LambdaQueryWrapper<CorpEntity>()
                .eq(CorpEntity::getWxCorpId, wxCorpId));
        List<WorkAgentEntity> agentList = workAgentService.list();
        if (corpEntity != null && !agentList.isEmpty()) {
            for (WorkAgentEntity workAgentEntity : agentList) {
                if (workAgentEntity.getCorpId().equals(corpEntity.getCorpId()) && workAgentEntity.getName().equals(wxSendMsgAppName)) {
                    log.info("wxSendMsgAgentId:{}",workAgentEntity.getWxAgentId());
                    return Integer.parseInt(workAgentEntity.getWxAgentId());
                }
            }
            throw new CheckedException("微信消息推送应用名称异常，请检查配置文件wx.sendMsg.appName或cp_work_agent表配置");
        } else {
            throw new CheckedException("wxCorpId:" + wxCorpId + "异常");
        }
    }

}
